/**
 * Copyright: Copyright (c)2011
 * Company: 易宝支付(YeePay)
 */
package net.loyintean.pearlshell.base.model.impl;

import java.sql.SQLException;
import java.util.List;

import net.loyintean.pearlshell.basedb.dao.BasicDao;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

/** @author：jun.lin@yeepay.com
 * @since：2015年4月5日 上午1:09:42
 * @version: */
public class BasicDao4Mybatis<T> implements BasicDao<T> {

	private SqlSessionFactory sessionFactory;

	private String totalCountKey = "totalCount";

	/** @see net.loyintean.pearlshell.basedb.dao.BasicDao#insertSingleDto(java.lang.Object,
	 *      java.lang.String) */
	@Override
	public int insertSingleDto(T dto, String statementId) throws SQLException {

		SqlSession session = sessionFactory.openSession();
		String realStatementId = generateStatementId(dto, statementId,
				"insertSingleDto");

		int count = session.insert(realStatementId, dto);

		return count;
	}

	/** @see net.loyintean.pearlshell.basedb.dao.BasicDao#deleteSingleDto(java.lang.Object,
	 *      java.lang.String) */
	@Override
	public int deleteSingleDto(T dto, String statementId) throws SQLException {

		SqlSession session = sessionFactory.openSession();
		String realStatementId = generateStatementId(dto, statementId,
				"deleteSingleDto");

		int count = session.delete(realStatementId, dto);

		return count;
	}

	/** @see net.loyintean.pearlshell.basedb.dao.BasicDao#updateSingleDto(java.lang.Object,
	 *      java.lang.String) */
	@Override
	public int updateSingleDto(T dto, String statementId) throws SQLException {

		SqlSession session = sessionFactory.openSession();
		String realStatementId = generateStatementId(dto, statementId,
				"updateSingleDto");

		int count = session.update(realStatementId, dto);

		return count;
	}

	/** @see net.loyintean.pearlshell.basedb.dao.BasicDao#selectSingleDto(java.lang.Object,
	 *      java.lang.String) */
	@Override
	public T selectSingleDto(T dto, String statementId) throws SQLException {

		SqlSession session = sessionFactory.openSession();
		String realStatementId = generateStatementId(dto, statementId,
				"selectSingleDto");

		T singleDto = session.selectOne(realStatementId, dto);

		return singleDto;
	}

	/** @see net.loyintean.pearlshell.basedb.dao.BasicDao#selectDtoList(java.lang.Object,
	 *      java.lang.String) */
	@Override
	public List<T> selectDtoList(T dto, String statementId) throws SQLException {

		SqlSession session = sessionFactory.openSession();
		String realStatementId = generateStatementId(dto, statementId,
				"selectDtoList");

		List<T> dtoList = session.selectList(realStatementId, dto);

		return dtoList;
	}

	/** @see net.loyintean.pearlshell.basedb.dao.BasicDao#selectPagedList(java.lang.Object,
	 *      java.lang.String) */
	@Override
	public List<T> selectPagedList(T dto, String statementId)
			throws SQLException {

		SqlSession session = sessionFactory.openSession();
		String realStatementId = generateStatementId(dto, statementId,
				"selectPagedList");

		List<T> dtoList = session.selectList(realStatementId, dto);

		return dtoList;
	}

	/** @see net.loyintean.pearlshell.basedb.dao.BasicDao#selectTotalCount(java.lang.Object,
	 *      java.lang.String) */
	@Override
	public int selectTotalCount(T dto, String statementId) throws SQLException {

		SqlSession session = sessionFactory.openSession();
		String realStatementId = generateStatementId(dto, statementId,
				"selectTotalCount");

		ResultHandler4TotalCount handler = new ResultHandler4TotalCount();
		handler.setTotalCountKey(totalCountKey);

		session.select(realStatementId, dto, handler);

		return handler.getTotalCount();
	}

	/** 生成mybatis的statement id
	 * <p>
	 * 如果入参statementId有值，那么直接使用它。<br>
	 * 否则，用dto的全路径名+入参来生成一个
	 * 
	 * @param dto
	 * @param statementId
	 * @param suffix
	 * @return */
	private String generateStatementId(T dto, String statementId, String suffix) {
		assert dto != null;

		return statementId != null ? statementId : (dto.getClass().getName()
				+ "." + suffix);

	}

	/** @param sessionFactory
	 *            the sessionFactory to set */
	protected void setSessionFactory(SqlSessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	/** @param totalCountKey
	 *            the totalCountKey to set */
	protected void setTotalCountKey(String totalCountKey) {
		this.totalCountKey = totalCountKey;
	}

}
